;--------------------------------------
;
; strins.asm
;
; insert source into destination
;
;

;--------------------------------------
;
; include defs, prototypes and macros
;

include tab6.inc

;--------------------------------------
;
; begin code segment
;

	.CODE

;--------------------------------------
;
; strins(int dest_index);
;
; strins requires that the
; PREPARE_STRING macro be utilized
; before strins is INVOKED
; 

strins	PROC PASCAL PUBLIC USES ds es si di,dest:PBYTE,srce:PBYTE,d_i:WORD
	LOCAL dest_length:WORD,srce_length:WORD

; initialize source

 IF mdl eq 3

; set dest es:[di]

        les     di,dest

; set srce ds:[si]

        lds     si,srce

  ELSE

        push    ds
        pop     es

; set dest es:[di]

        mov     di,dest

; set srce ds:[si]

        mov     si,srce

  ENDIF

; get destination string length
	
	sub	cx,cx                  ; set counter to 0
	mov	bx,di                  ; bx becomes offset

	.WHILE 1
	mov	al,es:[bx]
	.BREAK .IF (al==0)
	inc	cx
	inc	bx
	.ENDW

	mov	dest_length,cx

; get source string length

	sub	cx,cx                  ; set counter to 0
	mov	bx,si                  ; bx becomes offset

	.WHILE 1
	mov	al,ds:[bx]
	.BREAK .IF (al==0)
	inc	cx
	inc	bx
	.ENDW

	mov	srce_length,cx

; create space in dest buffer

	mov	dx,di
	add	dx,d_i          ; dx => insert start offset

	push	di                     ; save dest offset
	mov	bx,di                  ; transet dest offset to bx
	add	bx,dest_length         ; bx => dest end
	add	bx,srce_length         ; bx => offset to new dest end
	add	di,dest_length         ; di => current dest end
	mov	cx,srce_length         ; relocate srce_length bytes

	.REPEAT
	mov	al,BYTE PTR es:[di]    ; dest byte moves to
	mov	BYTE PTR es:[bx],al    ; new dest location
	dec	di                     ; go back one byte
	dec	bx
	.UNTIL (dx>di)	
	pop	di                     ; restore dest offset

; insert srce into newly created space

	add	di,d_i
	mov	cx,srce_length

	.REPEAT
	mov	al,BYTE PTR ds:[si]    ; get first srce byte
	mov	BYTE PTR es:[di],al    ; into dest
	inc	si
	inc	di
	dec	cx
	.UNTIL (cx==0)             ; break if at dest end


	ret	                       ; return to caller
strins	ENDP

;
; end of strins procedure
;
;--------------------------------------

	END

;
; end of strins.asm
;
;--------------------------------------


